#if defined (_MSC_VER)
#pragma once
#endif

#ifndef LM_CORE_SAMPLER_H
#define LM_CORE_SAMPLER_H

#include "lm.h"
#include "memory.h"
#include "rng.h"
#include "point.h"

struct Sample {
	Sample(Sampler *sampler, SurfaceIntegrator *surf, 
			VolumeIntegrator *vol, const Scene *scene);
	~Sample();
	Sample *Duplicate(int count) const;
	Point2 imageSample;
	Point2 lensSample;
	float time;
	vector<int> n1D, n2D;
	float **oneD;
	Point2 **twoD;
	int Add1D(int num) {
		n1D.push_back(num);
		return n1D.size() - 1;
	}
	int Add2D(int num) {
		n2D.push_back(num);
		return n2D.size() - 1;
	}
private:
	void AllocateSampleMemory();
//public:
	Sample() { 
		n1D.clear();
		n2D.clear();
		oneD = NULL; 
		twoD = NULL;
	}
};

class Sampler {
public:
	virtual ~Sampler();
	Sampler(int xstart, int xend, int ystart, int yend, int spp, bool lns, bool ts);
	virtual int GetMoreSamples(Sample *sample) = 0;
	virtual int MaximumSampleCount() = 0;
	virtual int RoundSize(int size) const = 0;
	virtual int totalSamples() const {
		return samplePerPixel * (xPixelEnd - xPixelStart) * (yPixelEnd - yPixelStart);
	}
	virtual Sampler *GetSubSampler(int num, int count) = 0;

	const int xPixelStart, xPixelEnd, yPixelStart, yPixelEnd;
	const int samplePerPixel;
	bool needLensSamples, needTimeSamples;
protected:
	// Sampler Protected Methods
	void ComputeSubWindow(int num, int count, int *xstart, int *xend, int *ystart, int *yend) const;

};

#endif	// LM_CORE_SAMPLER_H